﻿namespace CloudNinja.Metering.Providers.Configuration
{
    using System;
    using System.Configuration;

    using CloudNinja.Metering.Common.Configuration;
    using CloudNinja.Metering.Providers.Configuration.BlobBandwidth;
    using CloudNinja.Metering.Providers.Configuration.BlobSize;
    using CloudNinja.Metering.Providers.Configuration.DatabaseBandwidth;
    using CloudNinja.Metering.Providers.Configuration.DatabaseSize;

    public static class ProvidersConfigurationElementExtension
    {
        public static string GetDefaultTenantIdPattern(this ConfigurationElement configurationElement, string currentValue)
        {
            if (!currentValue.Equals(string.Empty))
            {
                return currentValue;
            }

            var configuration = configurationElement.CurrentConfiguration;

            var meteringConfig = configuration.Sections["MeteringConfiguration"] as MeteringSection;

            if (meteringConfig == null)
            {
                throw new ConfigurationErrorsException(
                    "Metering configuration is not named as MeteringConfiguration or no Metering configuration is found.");
            }

            foreach (var provider in meteringConfig.ProviderSettings.Providers)
            {
                var blobSizeProvider = provider as BlobSizeProviderElement;
                if (blobSizeProvider != null)
                {
                    var found = false;

                    foreach (var item in blobSizeProvider.BlobSizeMeteringMeteringProviderSettings.StorageAccounts)
                    {
                        var storageAccount = item as BlobSizeCollectionElement;
                        if (storageAccount != null)
                        {
                            found = storageAccount.GetHashCode().Equals(configurationElement.GetHashCode());
                        }

                        if (found)
                        {
                            break;
                        }
                    }

                    if (found)
                    {
                        return blobSizeProvider.BlobSizeMeteringMeteringProviderSettings.DefaultTenantIdPattern;
                    }
                }

                var blobBandwidthProvider = provider as BlobBandwidthProviderElement;
                if (blobBandwidthProvider != null)
                {
                    var found = false;

                    foreach (var item in blobBandwidthProvider.BlobBandwidthMeteringProviderSettings.StorageAccounts)
                    {
                        var storageAccount = item as BlobBandwidthCollectionElement;
                        if (storageAccount != null)
                        {
                            found = storageAccount.GetHashCode().Equals(configurationElement.GetHashCode());
                        }

                        if (found)
                        {
                            break;
                        }
                    }

                    if (found)
                    {
                        return blobBandwidthProvider.BlobBandwidthMeteringProviderSettings.DefaultTenantIdPattern;
                    }
                }

                var databaseSizeProviderElement = provider as DatabaseSizeMeteringProviderElement;
                if (databaseSizeProviderElement != null)
                {
                    var found = false;

                    foreach (var item in databaseSizeProviderElement.DatabaseSizeMeteringProviderSettings.DatabaseServers)
                    {
                        var collectionElement = item as DatabaseServersCollectionElement;
                        if (collectionElement != null)
                        {
                            found = collectionElement.GetHashCode().Equals(configurationElement.GetHashCode());
                        }

                        if (found)
                        {
                            break;
                        }
                    }

                    if (found)
                    {
                        return databaseSizeProviderElement.DatabaseSizeMeteringProviderSettings.DefaultTenantIdPattern;
                    }
                }

                var databaseBandwidhtElement = provider as DatabaseBandwidthMeteringProviderElement;
                if (databaseBandwidhtElement != null)
                {
                    var found = false;

                    foreach (var item in databaseBandwidhtElement.DatabaseBandwidthMeteringProviderSettings.DatabaseServers)
                    {
                        var collectionElement = item as DatabaseServersCollectionElement;
                        if (collectionElement != null)
                        {
                            found = collectionElement.GetHashCode().Equals(configurationElement.GetHashCode());
                        }

                        if (found)
                        {
                            break;
                        }
                    }

                    if (found)
                    {
                        return databaseBandwidhtElement.DatabaseBandwidthMeteringProviderSettings.DefaultTenantIdPattern;
                    }
                }
            }

            throw new ConfigurationErrorsException(string.Format("Cannot find a default value for {0}", currentValue));
        }
    }
}
